package RichardAI;

import static util.ForbiddenChecker.NO_FORBIDDEN;

import java.util.Vector;

import skeleton.Board;
import skeleton.ChessInfo;
import skeleton.Solution;
import util.ChessStat;
import util.ForbiddenChecker;
import util.Lib;
import util.Pair;

public class RSolution implements Solution {
	static final int MUST_WIN = 0;
	static int[] directx = {0, 1, 1, 1};
	static int[] directy = {1, 0, -1, 1};
	static ForbiddenChecker fchecker = new ForbiddenChecker();
	
	@Override
	public int solve(Board board, ChessInfo info) {
		// TODO Auto-generated method stub
		return 0;
	}
	
	public boolean checkWinByForbidden(ChessStat stat, Pair res) {
		if (stat.myColor == BLACK) return false;
		Vector<Pair> forbiddenPos = new Vector<Pair>();
		for (int i=0; i<LEN; ++i)
			for (int j=0; j<LEN; ++j)
				if (stat.board.data[i][j] == EMPTY) {
					if (fchecker.forbiddenCheck(stat.board.data, i, j)
							!= NO_FORBIDDEN)
						forbiddenPos.add(new Pair(i, j));
				}
		
		for(int i = 0;i < forbiddenPos.size(); ++i) {
			Pair p = forbiddenPos.get(i);
			stat.board.data[p.first][p.second] = WHITE;
			if(checkWinStyle(stat, res)) {
				stat.board.data[p.first][p.second] = EMPTY;
				return true;
			}
			stat.board.data[p.first][p.second] = EMPTY;
		}
		return false;
	}
	
	private boolean checkWinStyle(ChessStat stat, Pair res) {
		if (stat.myColor == WHITE) {
			for (int i=5; i<10; ++i)
				if (getWinChess(stat, res, i))
					return true;
		}
		if (getWinChess(stat, res, 4)) {
			return true;
		}
		return false;
	}
	
	private boolean getWinChess(ChessStat stat, Pair res, int x) {
		boolean forbidden = true;
		if (stat.live[x] > 0) {
			int sx, sy, di, chessx = 0, chessy = 0;
			for (int i=0; i<stat.live[x];) {
				sx = stat.liveVec[x].get(i).first;
				sy = stat.liveVec[x].get(i).second;
				di = stat.liveDirection[x].get(i);
				Lib.assertTrue(checkValidPut(stat, sx, sy, di, x));
				chessx = sx+x*directx[di];
				chessy = sy+x*directy[di];
				forbidden = false;
				break;
			}
			if (!forbidden) {
				res.first = chessx;
				res.second = chessy;
				return true;
			}
		}
		if (stat.dead[x] > 0) {
			int sx, sy, di, chessx = 0, chessy = 0;
			for (int i=0; i<stat.dead[x];) {
				sx = stat.deadVec[x].get(i).first;
				sy = stat.deadVec[x].get(i).second;
				di = stat.deadDirection[x].get(i);
				int p = -1;
				for (int j=1; j<=x; ++j) {
					if (checkValidPut(stat, sx, sy, di, j)) {
						chessx = sx + j*directx[di];
						chessy = sy + j*directy[di];
						p = j;
						break;
					}
				}
				if (p == -1) {
					Lib.assertTrue(checkValidPut(stat, sx, sy, di, -1));
					chessx = sx + p*directx[di];
					chessy = sy + p*directy[di];
				}
				forbidden = false;
				break;
			}
			if (!forbidden) {
				res.first = chessx;
				res.second = chessy;
				return true;
			}
		}
		return false;
	}
	
	private boolean checkValidPut(ChessStat stat, int sx, int sy, int di, int b) {
		int chessx = sx + b*directx[di];
		int chessy = sy + b*directy[di];
		if (!outBound(chessx,chessy))
			if (stat.board.data[chessx][chessy]==EMPTY)
				if (stat.myColor == BLACK && 
						fchecker.forbiddenCheck(stat.board.data,chessx,chessy) 
								!= NO_FORBIDDEN) {
					System.err.println("forbidden! at "+chessx+" "+chessy);
					return false;
				}
				else
					return true;
		return false;
	}
	
	private boolean outBound(int chessx, int chessy) {
		if (chessx<LEN && chessx>=0 && chessy<LEN && chessy >=0) return false;
		return true;
	}
}
